<!--
 * @Author: HenryTSZ
 * @Date: 2020-05-07 13:30:49
 * @Description:
 * @LastEditors: HenryTSZ
 * @LastEditTime: 2020-07-28 09:34:22
-->
<template>
  <div v-if="item.isSlot">
    <slot :name="`${item.prop}-e`" v-bind:model="modelValue" v-bind:item="item"></slot>
  </div>
  <component v-else :is="item.component" v-model="modelValue" :key="item.prop" v-bind="item" v-focus="item.focus"
    :placeholder="item.placeholder || `${handlePlaceholder(item.type)}${item.label}`"
    v-on="{ ...$listeners, ...item.events }">
    <template v-if="item.type === 'info'">
      {{ item.type === 'info' ? model[item.prop] : '' }}
    </template>
    <template v-if="item.select">
      <el-option v-for="option in item.select" :key="option[item.selectProps ? item.selectProps.value : 'value']"
        :value="option[item.selectProps ? item.selectProps.value : 'value']"
        :label="option[item.selectProps ? item.selectProps.label : 'label']" :disabled="option.disabled"></el-option>
    </template>
    <template v-if="item.select">
      <el-radio v-for="radio in item.radio" :key="radio[item.radioProps ? item.radioProps.value : 'value']"
        :label="radio[item.radioProps ? item.radioProps.value : 'value']" :disabled="radio.disabled">
        {{ radio[item.radioProps ? item.radioProps.label : 'label'] }}
      </el-radio>
    </template>
    <template v-if="item.select">
      <el-checkbox v-for="checkbox in item.checkbox" :key="checkbox" :label="checkbox"
        :disabled="checkbox.disabled"></el-checkbox>
    </template>
    <slot v-for="(value, key) in item.slots" :name="key" :slot="key">{{ value }}</slot>
  </component>
</template>

<script>

export default {
  name: 'EditableElements',
  components: {
    NumberInput: resolve => require(['./NumberInput'], resolve),
    RegInput: resolve => require(['./RegInput'], resolve),
    SelectTree: resolve => require(['./SelectTree'], resolve)
  },
  props: {
    item: {
      type: Object,
      default() {
        return {}
      }
    },
    model: {
      type: Object,
      default() {
        return {}
      }
    }
  },
  computed: {
    modelValue: {
      get() {
        const keys = this.item.prop.split('.');
        let temp = undefined;
        keys.forEach((key, index) => {
          if (index === 0) {
            temp = this.model?.[key];
          } else {
            temp = temp[key];
          }

        });
        return temp;
      },
      set(value) {
        if (value !== undefined) {
          this.deepSet(this.model, this.item.prop, value)
        }
      }
    }
  },
  methods: {
    handlePlaceholder(type) {
      if (['text', 'textarea', 'integer', 'decimal', 'input'].includes(type)) {
        return '请输入'
      } else if (
        ['select', 'radio', 'checkbox', 'date', 'cascader', 'switch', 'time', 'choose'].includes(type)
      ) {
        return '请选择'
      } else {
        return ''
      }
    },
    deepSet(obj, path, value) {
      const keys = path.split('.');
      if (keys.length === 1) {
        obj[keys[0]] = value;
      } else {
        let current = obj;
        for (let i = 0; i < keys.length; i++) {
          const key = keys[i];
          if (current[key] && i < keys.length - 1) {
            current = current[key];
          } else {
            current[key] = value;
          }
        }
      }

    },
  },
  directives: {
    focus: {
      // [vue v-focus v-show控制input的显示聚焦，第二次不生效问题_JavaScript_宣城-CSDN博客](https://blog.csdn.net/qq_37361812/article/details/93782340)
      // [页面一刷新让文本框自动获取焦点-- 和自定义v-focus指令 - 明月人倚楼 - 博客园](https://www.cnblogs.com/IwishIcould/p/12006378.html)
      update(el, { value, oldValue }) {
        if (value && value !== oldValue) {
          // 重点注意这里 当前元素是 div  所以要查到子元素中的 input
          const dom = el.querySelector('input') || el.querySelector('textarea')
          dom && dom.focus()
        }
      },
      inserted(el, { value }) {
        if (value) {
          // 重点注意这里 当前元素是 div  所以要查到子元素中的 input
          const dom = el.querySelector('input') || el.querySelector('textarea')
          dom && dom.focus()
        }
      }
    }
  }
}
</script>

<style lang="less" scoped>
.editable-elements {
  .el-select {
    width: 100%;
  }
}
</style>
